#include <deviceNormalParam.h>

// device normal parameter instance
struct devParamInfoNorm *paramNormInst()
{
    static struct devParamInfoNorm MCU_XDATA_TYPE deviceNormalParam;
    return &deviceNormalParam;
}

static const struct devParamInfoNorm MCU_CONST_TYPE defaultparam /*__attribute__((section(".text")))*/ = {
    sizeof(struct devParamInfoNorm) - sizeof(struct devParamHeadInfo), // paramSize
    0,                                                                 // paramCrc
    123456789,                                                         // prmT1
    23546,                                                             // prmT2
    1.6f,                                                              // prmT3
    "abcdefg",                                                         // prmT4
};

uint16_t paramNormGetDataSize(void)
{
    return paramGetDataSize(struct devParamInfoNorm);
    // (sizeof(struct devParamInfoNorm) - (sizeof(struct devParamHeadInfo)));
}
void *paramNormGetData(const struct devParamInfoNorm *parminfo)
{
    uint8_t *tmpptr = (uint8_t *)parminfo;
    return (tmpptr + deviceParameterCommonHeadSize);
}
int paramNormCvrtVal(struct devParamInfoNorm *parminfo)
{
    parminfo->paramHead.paramSize = convertOvtBigSysI16(parminfo->paramHead.paramSize);
    parminfo->paramHead.paramCrc = convertOvtBigSysI16(parminfo->paramHead.paramCrc);
    parminfo->prmT1 = convertOvtBigSysI32(parminfo->prmT1);
    parminfo->prmT2 = convertOvtBigSysI16(parminfo->prmT2);
    parminfo->prmT3 = convertOvtBigSysFloat(parminfo->prmT3);
    return 0;
}
int paramNormPrint()
{
    struct devParamInfoNorm *tmpNormalParam = paramNormInst();
    logdebug("printf device normal param------>");
    logdebug("size:%d", tmpNormalParam->paramHead.paramSize);
    logdebug("crc:%d", tmpNormalParam->paramHead.paramCrc);
    logdebug("t1:%d", tmpNormalParam->prmT1);
    logdebug("t2:%d", tmpNormalParam->prmT2);
    logdebug("t3:%f", tmpNormalParam->prmT3);
    logdebug("t4:%s", tmpNormalParam->prmT4);
    return 0;
}
int paramNormConfig(const void *parmconf, int configLevel)
{
    uint16_t tmpcrc16;
    struct devParamInfoNorm *desParm = (struct devParamInfoNorm *)paramNormInst();
    const struct devParamInfoNorm *newParam = (const struct devParamInfoNorm *)parmconf;
    logdebug("config:%s,level:%d", (newParam == NULL) ? "reset" : "set", configLevel);
    if (newParam == NULL)
    {
        newParam = &defaultparam;
    }
    else
    {
        tmpcrc16 = calculateUint16CrcHash(paramNormGetData(newParam), newParam->paramHead.paramSize);
        if (tmpcrc16 != newParam->paramHead.paramCrc)
        {
            logerror("%x,%x", tmpcrc16, newParam->paramHead.paramCrc);
            return -1;
        }
    }
    switch (configLevel)
    {
    case DEVICE_PARAM_CONFIG_LEVEL_0:
    {
        // configOneParameterCommon(struct devParamInfoNorm, deviceSerialNumber);
    }
    case DEVICE_PARAM_CONFIG_LEVEL_1:
    {
        configOneParameterCommon(struct devParamInfoNorm, prmT1);
    }
    case DEVICE_PARAM_CONFIG_LEVEL_2:
    {
        configOneParameterCommon(struct devParamInfoNorm, prmT2);
    }
    case DEVICE_PARAM_CONFIG_LEVEL_3:
    {
        configOneParameterCommon(struct devParamInfoNorm, prmT3);
    }
    case DEVICE_PARAM_CONFIG_LEVEL_4:
    {
        configOneParameterCommon(struct devParamInfoNorm, prmT4);
    }
    case DEVICE_PARAM_CONFIG_LEVEL_5: // defualt
    {
    }
    case DEVICE_PARAM_CONFIG_LEVEL_6:
    {
    }
    case DEVICE_PARAM_CONFIG_LEVEL_7:
    {
    }
    case DEVICE_PARAM_CONFIG_LEVEL_8:
    {
    }
    case DEVICE_PARAM_CONFIG_LEVEL_9:
    {
    }
    default:
    {
        break;
    }
    }
    paramCalcHeadInfo((struct devParamHeadInfo *)paramNormInst(), paramGetDataSize(struct devParamInfoNorm));
    return 0;
}
int paramNormReset(int configLevel)
{
    paramNormConfig(NULL, configLevel);
}

int paramCalcHeadInfo(struct devParamHeadInfo *parmptr, int parmsize)
{
    parmptr->paramSize = parmsize;
    parmptr->paramCrc = calculateUint16CrcHash(((void *)parmptr) + sizeof(struct devParamHeadInfo), parmptr->paramSize);
    return 0;
}

#if 0
#include <deviceNormalParam.h>
struct deviceParameterNormalInformOld
{
    struct
    {
        uint16_t paramSize;
        uint16_t paramCrc;
    };
    uint32_t prmT1;
    uint16_t prmT2;
};
struct deviceParameterNormalInformNew
{
    struct
    {
        uint16_t paramSize;
        uint16_t paramCrc;
    };
    uint32_t prmT1;
    uint16_t prmT2;
    float prmT3;
    uint8_t prmT4[10];
    uint32_t prmT5;
};
int main()
{
    struct deviceParameterNormalInformOld tmpparmOld;
    struct deviceParameterNormalInformNew tmpparmNew;
    char *tmpConstStr;
    // struct devParamInfoNorm *tmpNormalParam = paramNormInst();
    paramNormReset(0);
    paramNormPrint();
    memcpypro(&tmpparmOld, sizeof(tmpparmOld), paramNormInst(), sizeof(struct devParamInfoNorm));
    memcpypro(&tmpparmNew, sizeof(tmpparmNew), paramNormInst(), sizeof(struct devParamInfoNorm));

    tmpparmOld.prmT1 = 11;
    tmpparmOld.prmT2 = 12;
    paramCalcHeadInfo((struct devParamHeadInfo *)&tmpparmOld, paramGetDataSize(tmpparmOld));
    paramNormConfig(&tmpparmOld, 0);
    paramNormPrint();

    tmpparmNew.prmT1 = 21;
    tmpparmNew.prmT2 = 22;
    tmpparmNew.prmT3 = 23;
    memcpy(tmpparmNew.prmT4, "24-", 4);
    tmpparmNew.prmT5 = 25;
    paramCalcHeadInfo((struct devParamHeadInfo *)&tmpparmNew, paramGetDataSize(tmpparmNew));
    paramNormConfig(&tmpparmNew, 0);
    paramNormPrint();

    struct devParamInfoNorm tmpnormread;
    memcpy(&tmpnormread, paramNormInst(), sizeof(struct devParamInfoNorm));
    logHexData("parm norm data:", (const uint8_t *)&tmpnormread, sizeof(struct devParamInfoNorm));
    paramNormCvrtVal(&tmpnormread);
    logHexData("parm cvrt data:", (const uint8_t *)&tmpnormread, sizeof(struct devParamInfoNorm));
}
#endif
